/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package vue;

import dao.MediaDAO;
import java.util.Map.Entry;
import java.util.Set;
import media.Media;
import application.ApplicationController;
import application.FicheMediaController;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JTable;
import javax.swing.JTabbedPane;
import javax.swing.JPanel;
import java.util.ArrayList;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
import plugins.MediaPluginInterface;
import javax.swing.JLabel;
import plugins.RecherchePluginInterface;

/**
 * Définit la vue principale de l'application
 * @author Florian Minin & Khémon Beh
 */
public class vueBiblio extends JFrame {

    //Constantes utilisées définir les actionCommand des boutons
    //de la fenêtre
    final public static String BTN_AJOUTER = "Ajouter";
    final public static String BTN_AJOUTER_PLUGIN = "Ajouter Plugin";
    final public static String BTN_CONSULTER = "Consulter";
    final public static String BTN_SUPPRIMER = "Supprimer";
    final public static String BTN_QUITTER = "Quitter";
    final public static String BTN_RECHERCHER = "Rechercher";

    //Constantes associées aux fiches Media
    final public static String BTN_MODIFIER = "Modifier";
    final public static String BTN_SAUVEGARDER = "Sauvegarder";
    
    //Liste contenant l'ensemblde des tables de média
    private List<JTable> listeTable;

    private JMenuBar menuPrincipal;
    private JMenu menuFichier;
    private JMenu menuEdition;
    private JMenu menuPlugin;
    private JMenuItem jmi_Ajouter;
    private JMenuItem jmi_AjouterPlugin;
    private JMenuItem jmi_Consulter;
    private JMenuItem jmi_Supprimer;
    private JMenuItem jmi_Quitter;
    private JTabbedPane tp_Onglets;
    private JPanel pnl_Musiques;
    private JPanel pnl_Photos;
    private JPanel pnl_Videos;
    private JTable jt_donneesMusique;
    private JTable jt_donneesVideos;
    private JTable jt_donneesPhotos;
    private JScrollPane jsp_Musiques;
    private JScrollPane jsp_Photos;
    private JScrollPane jsp_Videos;
    
    //Map qui stock toutes les fiches media
    private Map<String, FicheMediaAbstract> mapFicheMedia;
    //Contient la fiche média en cours
    private FicheMediaAbstract ficheMediaEnCours;
    
    private JLabel lblErreur;

    public vueBiblio() {
        listeTable = new ArrayList<JTable>();
        setResizable(false);

        mapFicheMedia = new TreeMap<String, FicheMediaAbstract>();

        setResizable(true);
        setVisible(true);
        setTitle("Bibliotheque Multimedia");

        //Instanciation des menus et des items
        menuPrincipal = new JMenuBar();
        menuFichier = new JMenu("Fichier");
        jmi_Ajouter = new JMenuItem("Ajouter à la bibliothèque");
        jmi_Quitter = new JMenuItem("Quitter");
        menuEdition = new JMenu("Edition");
        jmi_Consulter = new JMenuItem("Consulter");
        jmi_Supprimer = new JMenuItem("Supprimer");
        menuPlugin = new JMenu("Plugins");
        jmi_AjouterPlugin = new JMenuItem("Ajouter un plugin");

        //Mise en place des menus
        menuFichier.add(jmi_Ajouter);
        menuFichier.addSeparator();
        menuFichier.add(jmi_Quitter);
        menuPlugin.add(jmi_AjouterPlugin);
        menuEdition.add(jmi_Consulter);
        menuEdition.add(jmi_Supprimer);
        menuPrincipal.add(menuFichier);
        menuPrincipal.add(menuEdition);
        menuPrincipal.add(menuPlugin);

        //Raccourcis clavier
        jmi_Ajouter.setAccelerator(KeyStroke.getKeyStroke(
                KeyEvent.VK_A, ActionEvent.ALT_MASK));
        jmi_Quitter.setAccelerator(KeyStroke.getKeyStroke(
                KeyEvent.VK_Q, ActionEvent.ALT_MASK));
        jmi_Consulter.setAccelerator(KeyStroke.getKeyStroke(
                KeyEvent.VK_C, ActionEvent.ALT_MASK));
        jmi_Supprimer.setAccelerator(KeyStroke.getKeyStroke(
                KeyEvent.VK_DELETE, ActionEvent.ALT_MASK));
        jmi_AjouterPlugin.setAccelerator(KeyStroke.getKeyStroke(
                KeyEvent.VK_P, ActionEvent.ALT_MASK));

        setJMenuBar(menuPrincipal);
        GridBagLayout gridBagLayout = new GridBagLayout();
        gridBagLayout.columnWidths = new int[]{894, 0};
        gridBagLayout.rowHeights = new int[]{433, 0, 0};
        gridBagLayout.columnWeights = new double[]{1.0, Double.MIN_VALUE};
        gridBagLayout.rowWeights = new double[]{1.0, 0.0, Double.MIN_VALUE};
        getContentPane().setLayout(gridBagLayout);

        tp_Onglets = new JTabbedPane(JTabbedPane.TOP);
        tp_Onglets.setToolTipText("");
        GridBagConstraints gbc_tp_Onglets = new GridBagConstraints();
        gbc_tp_Onglets.insets = new Insets(0, 0, 5, 0);
        gbc_tp_Onglets.fill = GridBagConstraints.HORIZONTAL;
        gbc_tp_Onglets.gridx = 0;
        gbc_tp_Onglets.gridy = 0;
        getContentPane().add(tp_Onglets, gbc_tp_Onglets);

        pnl_Musiques = new JPanel();
        tp_Onglets.insertTab("Musiques", null, pnl_Musiques, null, tp_Onglets.getTabCount());
        GridBagLayout gbl_pnl_Musiques = new GridBagLayout();
        gbl_pnl_Musiques.columnWidths = new int[]{30, 0, 26, 0};
        gbl_pnl_Musiques.rowHeights = new int[]{60, 233, 50, 0};
        gbl_pnl_Musiques.columnWeights = new double[]{0.0, 1.0, 0.0, Double.MIN_VALUE};
        gbl_pnl_Musiques.rowWeights = new double[]{0.0, 1.0, 1.0, Double.MIN_VALUE};
        pnl_Musiques.setLayout(gbl_pnl_Musiques);

        jsp_Musiques = new JScrollPane();
        GridBagConstraints gbc_jsp_Musiques = new GridBagConstraints();
        gbc_jsp_Musiques.gridheight = 2;
        gbc_jsp_Musiques.insets = new Insets(0, 0, 5, 5);
        gbc_jsp_Musiques.fill = GridBagConstraints.BOTH;
        gbc_jsp_Musiques.gridx = 1;
        gbc_jsp_Musiques.gridy = 1;
        pnl_Musiques.add(jsp_Musiques, gbc_jsp_Musiques);

        jt_donneesMusique = new JTable();
        TableModele<Media> modeleMusique = new TableModeleMusique();
        jt_donneesMusique.setModel(modeleMusique);
        jsp_Musiques.getVerticalScrollBar().setVisible(true);
        jsp_Musiques.getHorizontalScrollBar().setVisible(true);
        jsp_Musiques.setViewportView(jt_donneesMusique);
        jsp_Musiques.setVisible(true);

        pnl_Photos = new JPanel();
        tp_Onglets.insertTab("Photos", null, pnl_Photos, null, tp_Onglets.getTabCount());
        GridBagLayout gbl_pnl_Photos = new GridBagLayout();
        gbl_pnl_Photos.columnWidths = new int[]{30, 0, 26, 0};
        gbl_pnl_Photos.rowHeights = new int[]{60, 233, 50, 0};
        gbl_pnl_Photos.columnWeights = new double[]{0.0, 1.0, 0.0, Double.MIN_VALUE};
        gbl_pnl_Photos.rowWeights = new double[]{0.0, 1.0, 1.0, Double.MIN_VALUE};
        pnl_Photos.setLayout(gbl_pnl_Photos);

        jsp_Photos = new JScrollPane();
        GridBagConstraints gbc_jsp_Photos = new GridBagConstraints();
        gbc_jsp_Photos.gridheight = 2;
        gbc_jsp_Photos.insets = new Insets(0, 0, 5, 5);
        gbc_jsp_Photos.fill = GridBagConstraints.BOTH;
        gbc_jsp_Photos.gridx = 1;
        gbc_jsp_Photos.gridy = 1;
        pnl_Photos.add(jsp_Photos, gbc_jsp_Photos);

        jt_donneesPhotos = new JTable();
        TableModele<Media> modelePhoto = new TableModelePhoto();
        jt_donneesPhotos.setModel(modelePhoto);
        jsp_Photos.setViewportView(jt_donneesPhotos);
        jsp_Photos.setVisible(true);
        jsp_Photos.createHorizontalScrollBar();
        jsp_Photos.createVerticalScrollBar();

        pnl_Videos = new JPanel();
        tp_Onglets.insertTab("Videos", null, pnl_Videos, null, tp_Onglets.getTabCount());
        GridBagLayout gbl_pnl_Videos = new GridBagLayout();
        gbl_pnl_Videos.columnWidths = new int[]{30, 806, 24, 0};
        gbl_pnl_Videos.rowHeights = new int[]{60, 233, 50, 0};
        gbl_pnl_Videos.columnWeights = new double[]{0.0, 1.0, 0.0, Double.MIN_VALUE};
        gbl_pnl_Videos.rowWeights = new double[]{1.0, 1.0, 1.0, Double.MIN_VALUE};
        pnl_Videos.setLayout(gbl_pnl_Videos);

        jsp_Videos = new JScrollPane();
        GridBagConstraints gbc_jsp_Videos = new GridBagConstraints();
        gbc_jsp_Videos.gridheight = 2;
        gbc_jsp_Videos.fill = GridBagConstraints.BOTH;
        gbc_jsp_Videos.insets = new Insets(0, 0, 5, 5);
        gbc_jsp_Videos.gridx = 1;
        gbc_jsp_Videos.gridy = 1;
        pnl_Videos.add(jsp_Videos, gbc_jsp_Videos);

        jt_donneesVideos = new JTable();
        jt_donneesVideos.setFillsViewportHeight(true);
        jt_donneesVideos.setShowGrid(false);
        jt_donneesVideos.setShowHorizontalLines(false);
        jt_donneesVideos.setShowVerticalLines(false);
        TableModele<Media> modeleVideo = new TableModeleVideo();
        jt_donneesVideos.setModel(modeleVideo);
        jsp_Videos.setViewportView(jt_donneesVideos);
        jsp_Videos.createHorizontalScrollBar();
        jsp_Videos.createVerticalScrollBar();
        jsp_Videos.setVisible(true);

        jt_donneesVideos.getColumnModel().getColumn(0).setPreferredWidth(35);
        jmi_Ajouter.setActionCommand(BTN_AJOUTER);
        jmi_AjouterPlugin.setActionCommand(BTN_AJOUTER_PLUGIN);
        jmi_Consulter.setActionCommand(BTN_CONSULTER);
        jmi_Supprimer.setActionCommand(BTN_SUPPRIMER);
        jmi_Quitter.setActionCommand(BTN_QUITTER);

        listeTable.add(jt_donneesMusique);
        listeTable.add(jt_donneesPhotos);
        listeTable.add(jt_donneesVideos);

        lblErreur = new JLabel("");
        lblErreur.setForeground(Color.red);
        GridBagConstraints gbc_lblErreur = new GridBagConstraints();
        gbc_lblErreur.fill = GridBagConstraints.HORIZONTAL;
        gbc_lblErreur.gridx = 0;
        gbc_lblErreur.gridy = 1;
        getContentPane().add(lblErreur, gbc_lblErreur);

        //Redimensionnement de la fenêtre
        setSize(new Dimension(792, 559));
        pack();

    }

    /**
     * Gere l'abonnement des composants de la fenêtre
     * @param ctrl Controlleur qui va transferer les informations
     */
    public void abonnementComponents(ApplicationController ctrl) {
        jmi_Consulter.addActionListener(ctrl);
        jmi_Supprimer.addActionListener(ctrl);
        jmi_Ajouter.addActionListener(ctrl);
        jmi_AjouterPlugin.addActionListener(ctrl);
        jmi_Quitter.addActionListener(ctrl);
    }

    /**
     * Vérifie si une ligne est selectionnée dans la table de média
     * @return <tt>Boolean</tt> Vrai si une ligne est selectionnée, faux sinon.
     */
    public boolean isLigneSelectionnee() {
        JTable table = listeTable.get(indiceOngletSelectionne());
        if (table.getSelectedColumnCount() == 0) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * Récupere le media selectionne par l'utilisateur
     * @return <tt>Media</tt> correspondant au media selectionne
     * <tt>null</tt> si aucun media n'est selectionne
     */
    public Media getMediaSelectionne() {
        //Retourne le modele correspondant au media selectionne
        JTable table = listeTable.get(indiceOngletSelectionne());
        TableModele<Media> modele = (TableModele<Media>) table.getModel();
        return modele.getObjetSelectionne(table.getSelectedRow());
    }

    /**
     * Supprime la ligne selectionnee
     */
    public void supprimeLigneSelectionnee() {
        JTable table = listeTable.get(indiceOngletSelectionne());
        TableModele modele = (TableModele) table.getModel();
        //Supprime la ligne selectionnée
        modele.supprimeLigne(table.getSelectedRow());
    }

    /**
     * Ouvre une fiche media correspondant a la ligne selectionnée et ferme
     * l'ancienne fiche media si celle ci est ouverte
     * @param media Media a afficher
     * @param dao DAO du media
     * @param ctrl Controlleur qui va gerer les composants de la fiche media
     */
    public void ouvreUneFicheMedia(Media media,MediaDAO dao) {
        if(ficheMediaEnCours != null){
            ficheMediaEnCours.dispose();
        }
        ficheMediaEnCours = mapFicheMedia.get(media.getType());
        ficheMediaEnCours.chargerMedia(media);
        FicheMediaController controller = new FicheMediaController(ficheMediaEnCours,dao);
        ficheMediaEnCours.abonnementComponents(controller);
    }

    /**
     * Enregistre les media de la liste passé en paramètre
     * a l'indice spécifié et rafraichit l'affichage.
     * @param indice indice de la table a rafraichir
     * @param listeMedia ensemble des medias de la table
     */
    public void majTable(int indice, List<Media> listeMedia) {
        //Si la liste n'est pas vide
        if (!listeMedia.isEmpty()) {
            JTable table = listeTable.get(indice);
            TableModele modele = (TableModele) table.getModel();
            //Rafraichissement de la table
            modele.maj(listeMedia);
        }
    }

    /**
     * Retourne l'indice de la ligne selectionnée
     * @return un entier correspondant a la ligne selectionnée. -1
     * si aucune ligne n'est choisie.
     */
    public int indiceOngletSelectionne() {
        return this.tp_Onglets.getModel().getSelectedIndex();
    }

    /**
     * Retourne le media modifié par l'utilisateur
     * @param idFicheMedia identifiant du média 
     * @return un <tt>Media</tt> correspondant a la derniere fiche media ouverte
     */
    public Media retourneModifications() {
        if (ficheMediaEnCours == null) {
            return null;
        }
        return ficheMediaEnCours.getMedia();
    }

    /**
     * Intègre les nouveau média a la vue en ajoutant un nouvel onglet
     * ainsi que son contenu
     * @param listeMediaPlugin
     */
    public void integrerPlugins(MediaPluginInterface[] listeMediaPlugin) {
        for (int i = 0; i < listeMediaPlugin.length; i++) {
            integrerPlugin(listeMediaPlugin[i]);
        }
    }

    /**
     * Intègre le nouveau media
     * @param MediaPluginInterface plugin a intégrer a la vue
     */
    public void integrerPlugin(MediaPluginInterface mediaPlugin) {
        //Ajout du nouvel onglet en lui associant le panel du nouveau média et en définissant
        //le libellé de l'onglet par le type du média
        tp_Onglets.insertTab(mediaPlugin.getTypeMedia(), null, mediaPlugin.getPanelMedia(), null, tp_Onglets.getTabCount());
        //Ajout de la table du plugin a la liste des tables de média
        listeTable.add(mediaPlugin.getJTableMedia());
        //Ajout de la fiche média a la liste de fiche média.
        mapFicheMedia.put(mediaPlugin.getTypeMedia(), mediaPlugin.getDAOMedia().getFicheMedia());
    }

    /**
     * Extrait les fiches média d'un ensemble de DAO.
     * @param allDAO ensemble de DAO.
     */
    public void recupererFichesMedia(Set<Entry<Integer, MediaDAO>> allDAO) {
        //Pour chaque DAO de l'ensemble
        for (Entry<Integer, MediaDAO> dao : allDAO) {
            //On ajoute la fiche média a la map en lui donnant comme clé le type du média
            ajouterFicheMedia(dao.getValue().getTypeMedia(), dao.getValue().getFicheMedia());
        }
    }

    /**
     * Ajoute une fiche média a map de fiche média
     * @param typeMedia Type du média qui correspondra a la clé
     * @param ficheMedia fiche du média qui correspondra a la valeur
     */
    public void ajouterFicheMedia(String typeMedia, FicheMediaAbstract ficheMedia) {
        mapFicheMedia.put(typeMedia, ficheMedia);
    }

    /**
     * Intègre un nouveau plugin de recherche dans la vue
     * @param pluginRecherche
     */
    public void integrerPluginRecherche(RecherchePluginInterface pluginRecherche,
            ApplicationController ctrl) {
        JMenu menuRecherche = pluginRecherche.getMenuRecherche();
        //Ajoute le nouveau menu a la barre
        menuPrincipal.add(menuRecherche);
        menuRecherche.addActionListener(ctrl);
        //Rafraichit le contenu de la barre
        setJMenuBar(menuPrincipal);
    }

    //Ensemble des messages d'erreur de la fenêtre principale
    
    public void setErreurChargementPlugin(){
        lblErreur.setText("Une erreur est survenue lors du chargement de(s) plugin(s)");
    }

    public void setErreurAucunPlugin() {
        lblErreur.setText("Aucun plugin précédemment chargé");
    }
    public void setErreurFichierSerialisation(){
        lblErreur.setText("Un problème est survenu avec le fichier de sérialisation");
    }

    public void setLabelErreurABlanc() {
        lblErreur.setText("");
    }

    public void setErreurSerialisable() {
        lblErreur.setText("Erreur: la classe de l'objet doit étendre sérializable pour être sérialisé");
    }

    public void setErreurPluginIntegre() {
        lblErreur.setText("Ce plugin est déjà integré");
    }

    public void setErreurAucuneLigneSelectionnee() {
        lblErreur.setText("Aucune ligne n'est selectionnée.");
    }

    public void setErreurIntegrationPlugin() {
        lblErreur.setText("Erreur lors de l'intégration des plugins");
    }
    
}
